package cn.melonlib.cores.aop.comp.result;

import cn.melonlib.cores.aop.comp.TransToViewExecutor;
import cn.melonlib.cores.commons.model.entity.IEntity;
import cn.melonlib.cores.jpa.model.bean.impl.PaginationList;
import cn.melonlib.cores.model.anno.WorkerModel;
import cn.melonlib.cores.model.anno.WorkerService;
import org.springframework.aop.support.AopUtils;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Component("defaultTrans")
public class DefaultTransToViewExecutor extends ApplicationObjectSupport implements TransToViewExecutor<Object,Object,Object> {
    public Object trans(Object data, Object bean, Method method) throws Exception{
        WorkerService workerService=AnnotationUtils.findAnnotation(AopUtils.getTargetClass(bean), WorkerService.class);
        WorkerModel workerModel=workerService.model();

        if(workerModel.modelType().equals(workerModel.voType())){
            return data;
        }else{
            if(data instanceof IEntity) {
                if(!workerModel.modelType().isAssignableFrom(data.getClass())){
                    return data;
                }
                return workerModel.voType().getConstructor(workerModel.modelType()).newInstance(data);
            }else if(data instanceof PaginationList){
                return PaginationList.createOffset(((List<?>) data).stream().map(item-> {
                    try {
                        return workerModel.voType().getConstructor(workerModel.modelType()).newInstance(item);
                    } catch (Exception e) {
                        logger.error(e.getMessage(),e);
                        return item;
                    }
                }).filter(Objects::nonNull).collect(Collectors.toList()),((PaginationList<?>) data).getOffset(),((PaginationList<?>) data).getLimit(),((PaginationList<?>) data).getTotal());
            }else if(data instanceof List){
                return ((List<?>) data).stream().map(item-> {
                    try {
                        return workerModel.voType().getConstructor(workerModel.modelType()).newInstance(item);
                    } catch (Exception e) {
                        logger.error(e.getMessage(),e);
                        return item;
                    }
                }).filter(Objects::nonNull).collect(Collectors.toList());
            }else{
                return data;
            }

        }
    }
}
